﻿using LdtJudge.DataEngine.Model.Collection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

namespace LdtJudge.DataEngine.Common.CommHelp
{
    public class ParseLocationConfig
    {
        /// <summary>
        /// 解析定位配置信息
        /// </summary>
        /// <param name="xmlStr">配置信息</param>
        /// <param name="doc">分析或是优选后的xml  当number=0时，需要在xml中获取到最新的阶段</param>
        /// <returns></returns>
        public List<CTLocationModel> GetLocationModels(string xmlStr,XmlDocument doc,string casetypestr)
        {
            //string files = System.IO.File.ReadAllText(@"C:\Users\Administrator\Downloads\elementpath.xml");
            //xmlStr = files;
            LocationModel locationModels = new LocationModel();
            locationModels.cTLocationModels = new List<CTLocationModel>();
            XDocument xdoc = XDocument.Parse(xmlStr);
            XElement root = xdoc.Root;
            foreach (XElement casetype in root.Elements("casetype"))
            {
                CTLocationModel cTLocation = new CTLocationModel();
                cTLocation.docLocations = new List<DOCLocationModel>();
                if (casetype.Attribute("code") != null)
                {
                    cTLocation.CaseType = casetype.Attribute("code").Value;
                }
                foreach (XElement booktype in casetype.Elements("booktype"))
                {
                    DOCLocationModel docLocation = new DOCLocationModel();
                    string bookName = string.Empty;
                    if (booktype.Attribute("code") != null)
                    {
                        docLocation.DocType = booktype.Attribute("code").Value;
                    }
                    if (booktype.Attribute("number") != null)
                    {
                        docLocation.Number = Convert.ToInt32(booktype.Attribute("number").Value);
                    }
                    if (booktype.Attribute("path") != null)
                    {
                        docLocation.DocPath = booktype.Attribute("path").Value;
                    }
                    
                    foreach (XElement element in booktype.Elements("element"))
                    {
                        if (element.Attribute("path") != null)
                        {
                            docLocation.EelementPaht = element.Attribute("path").Value;
                        }
                    }
                    foreach (XElement element in booktype.Elements("mergelement"))
                    {
                        if (element.Attribute("path") != null)
                        {
                            docLocation.MergeElmentPath = element.Attribute("path").Value;
                        }
                    }
                    foreach (XElement element in booktype.Elements("reasonelement"))
                    {
                        string caseCauseRoute = string.Empty;
                        if (element.Attribute("path") != null)
                        {
                            docLocation.ReasoneELementPath = element.Attribute("path").Value;
                        }
                    }

                    foreach (XElement element in booktype.Elements("judgeelement"))
                    {
                        string caseCauseRoute = string.Empty;
                        if (element.Attribute("path") != null)
                        {
                            docLocation.JudgeElementPaht = element.Attribute("path").Value;
                        }
                    }
                    cTLocation.docLocations.Add(docLocation);
                }
                locationModels.cTLocationModels.Add(cTLocation);
            }

            #region 非文书类的数据源的定位配置处理
            foreach (var item in locationModels.cTLocationModels.Where(a=> a.CaseType.ToLower()==casetypestr.ToLower()))
            {
                var doclocs = item.docLocations.Where(a => a.DocPath == null);
                var doclocations = item.docLocations.Where(a => !string.IsNullOrEmpty(a.DocPath) && a.Number>0)?.ToList();
                foreach (var docloc in doclocs)
                {
                    if (docloc.Number == 0 && doclocations!=null && doclocations.Count()>0)
                    {
                        var pointDocLoc = GetLastStage(doc, doclocations);
                        if (pointDocLoc != null)
                        {
                            docloc.DocPath = pointDocLoc.DocPath;
                            docloc.EelementPaht = pointDocLoc.EelementPaht;
                            docloc.MergeElmentPath = pointDocLoc.MergeElmentPath;
                            docloc.ReasoneELementPath = pointDocLoc.ReasoneELementPath;
                        }
                    }
                    else
                    {
                        var pointDocLoc = item.docLocations.Where(a => a.Number == docloc.Number);
                        if (pointDocLoc != null && pointDocLoc.Count() > 0)
                        {
                            docloc.DocPath = pointDocLoc.First().DocPath;
                            docloc.EelementPaht = pointDocLoc.First().EelementPaht;
                            docloc.MergeElmentPath = pointDocLoc.First().MergeElmentPath;
                            docloc.ReasoneELementPath = pointDocLoc.First().ReasoneELementPath;
                        }
                    }
                }
            }
            #endregion

            return locationModels.cTLocationModels;
        }
       
        /// <summary>
        /// 得到某个案件类型下的文书定位信息
        /// </summary>
        /// <param name="casetype">案件类型</param>
        /// <returns></returns>
        public List<DOCLocationModel> GetDOCLocations(string casetype, List<CTLocationModel> cTLocations)
        {
            return cTLocations.Where(a => a.CaseType == casetype)?.FirstOrDefault().docLocations;
        }

        /// <summary>
        /// 查找最新阶段
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="cTLocations"></param>
        /// <returns></returns>
        private DOCLocationModel GetLastStage(XmlDocument doc, List<DOCLocationModel> cTLocations)
        {
            DOCLocationModel re = new DOCLocationModel();
            List<DOCLocationModel> orderedModel = new List<DOCLocationModel>();
            orderedModel = cTLocations.OrderByDescending(a => a.Number).ToList();
            foreach (var item in orderedModel)
            {
                if (doc !=null)
                {
                    if (doc.SelectSingleNode(item.DocPath) != null)
                    {
                        re = item;
                        break;
                    }
                }
                
            }
            return re;
        }

        /// <summary>
        /// 解析要素定位信息
        /// 首先通过案由要素定位配置获取数据，如果无法确定阶段数据，通过要素阶段配置获取阶段数据
        /// </summary>
        /// <param name="locationConfig">案由要素定位配置</param>
        /// <param name="stageConfig">要素阶段配置</param>
        /// <param name="doc">案件要素优选结果</param>
        /// <param name="casetypestr">案件类型</param>
        /// <param name="docType">文书类型</param>
        /// <returns></returns>
        public List<DOCLocationModel> GetLocationModel(string locationConfig,string stageConfig,XmlDocument doc,string casetypestr,string docType)
        {
            List<DOCLocationModel> locationModels = new List<DOCLocationModel>();
            DOCLocationModel locationModel = new DOCLocationModel();
            //通过案由要素定位配置获取数据
            locationModel = GetLocationModelByDocType(locationConfig, casetypestr, docType);
            if(locationModel == null || string.IsNullOrWhiteSpace(locationModel.DocPath))
            {
                //通过要素阶段配置获取阶段数据
                locationModel = GetLocationModelByStage(stageConfig,doc,casetypestr);
                locationModel.DocType = docType;
            }

            locationModels.Add(locationModel);
            return locationModels;
        }

        /// <summary>
        /// 通过案由要素定位配置获取数据
        /// </summary>
        /// <param name="xmlStr">案由要素定位配置</param>
        /// <param name="casetypestr">案件类型</param>
        /// <param name="docType">文书类型</param>
        /// <returns></returns>
        public DOCLocationModel GetLocationModelByDocType(string xmlStr, string casetypestr,string docType)
        {
            DOCLocationModel locationModel = null;
            if(!string.IsNullOrWhiteSpace(xmlStr))
            {
                LocationModel locationModels = new LocationModel();
                locationModels.cTLocationModels = new List<CTLocationModel>();

                XDocument xdoc = XDocument.Parse(xmlStr);
                XElement root = xdoc.Root;
                foreach (XElement casetype in root.Elements("casetype"))
                {
                    CTLocationModel cTLocation = new CTLocationModel();
                    cTLocation.docLocations = new List<DOCLocationModel>();
                    if (casetype.Attribute("code") != null)
                    {
                        cTLocation.CaseType = casetype.Attribute("code").Value;
                    }
                    foreach (XElement booktype in casetype.Elements("booktype"))
                    {
                        DOCLocationModel docLocation = new DOCLocationModel();
                        if (booktype.Attribute("code") != null)
                        {
                            docLocation.DocType = booktype.Attribute("code").Value;
                        }
                        if (booktype.Attribute("number") != null)
                        {
                            docLocation.Number = Convert.ToInt32(booktype.Attribute("number").Value);
                        }
                        if (booktype.Attribute("path") != null)
                        {
                            docLocation.DocPath = booktype.Attribute("path").Value;
                        }

                        foreach (XElement element in booktype.Elements("element"))
                        {
                            if (element.Attribute("path") != null)
                            {
                                docLocation.EelementPaht = element.Attribute("path").Value;
                            }
                        }
                        foreach (XElement element in booktype.Elements("mergelement"))
                        {
                            if (element.Attribute("path") != null)
                            {
                                docLocation.MergeElmentPath = element.Attribute("path").Value;
                            }
                        }
                        foreach (XElement element in booktype.Elements("reasonelement"))
                        {
                            string caseCauseRoute = string.Empty;
                            if (element.Attribute("path") != null)
                            {
                                docLocation.ReasoneELementPath = element.Attribute("path").Value;
                            }
                        }

                        foreach (XElement element in booktype.Elements("judgeelement"))
                        {
                            string caseCauseRoute = string.Empty;
                            if (element.Attribute("path") != null)
                            {
                                docLocation.JudgeElementPaht = element.Attribute("path").Value;
                            }
                        }
                        if (!string.IsNullOrWhiteSpace(docLocation.DocPath))
                        {
                            cTLocation.docLocations.Add(docLocation);
                        }

                    }
                    locationModels.cTLocationModels.Add(cTLocation);
                }
                var cTlocation = locationModels.cTLocationModels.FirstOrDefault(x => x.CaseType.ToLower() == casetypestr.ToLower());
                if (cTlocation != null)
                {
                    if (cTlocation.docLocations.Any())
                    {
                        locationModel = cTlocation.docLocations.FirstOrDefault(x => x.DocType.ToLower() == docType.ToLower());
                    }
                }
            }
            return locationModel;
        }

        /// <summary>
        /// 通过要素阶段配置获取阶段数据
        /// </summary>
        /// <param name="xmlStr">要素阶段配置</param>
        /// <param name="doc">案件要素优选结果</param>
        /// <param name="casetypestr">案件类型</param>
        /// <returns></returns>
        public DOCLocationModel GetLocationModelByStage(string xmlStr,XmlDocument doc,string casetypestr)
        {
            DOCLocationModel locationModel = new DOCLocationModel();
            if(!string.IsNullOrWhiteSpace(xmlStr))
            {
                LocationModel locationModels = new LocationModel();
                locationModels.cTLocationModels = new List<CTLocationModel>();
                XDocument xdoc = XDocument.Parse(xmlStr);
                XElement root = xdoc.Root;
                foreach (XElement casetype in root.Elements("casetype"))
                {
                    CTLocationModel cTLocation = new CTLocationModel();
                    cTLocation.docLocations = new List<DOCLocationModel>();
                    if (casetype.Attribute("code") != null)
                    {
                        cTLocation.CaseType = casetype.Attribute("code").Value;
                    }
                    foreach (XElement stageItem in casetype.Elements("stage"))
                    {
                        if (stageItem != null)
                        {
                            foreach (XElement stageDetail in stageItem.Elements("stagecode"))
                            {
                                DOCLocationModel docLocation = new DOCLocationModel();
                                if (stageDetail.Attribute("number") != null)
                                {
                                    docLocation.Number = Convert.ToInt32(stageDetail.Attribute("number").Value);
                                }
                                if (stageDetail.Attribute("path") != null)
                                {
                                    docLocation.DocPath = stageDetail.Attribute("path").Value;
                                }

                                foreach (XElement element in stageDetail.Elements("element"))
                                {
                                    if (element.Attribute("path") != null)
                                    {
                                        docLocation.EelementPaht = element.Attribute("path").Value;
                                    }
                                }
                                foreach (XElement element in stageDetail.Elements("mergelement"))
                                {
                                    if (element.Attribute("path") != null)
                                    {
                                        docLocation.MergeElmentPath = element.Attribute("path").Value;
                                    }
                                }
                                foreach (XElement element in stageDetail.Elements("reasonelement"))
                                {
                                    string caseCauseRoute = string.Empty;
                                    if (element.Attribute("path") != null)
                                    {
                                        docLocation.ReasoneELementPath = element.Attribute("path").Value;
                                    }
                                }
                                foreach (XElement element in stageDetail.Elements("judgeelement"))
                                {
                                    string caseCauseRoute = string.Empty;
                                    if (element.Attribute("path") != null)
                                    {
                                        docLocation.JudgeElementPaht = element.Attribute("path").Value;
                                    }
                                }
                                if (!string.IsNullOrWhiteSpace(docLocation.DocPath))
                                {
                                    cTLocation.docLocations.Add(docLocation);
                                }
                            }
                        }
                    }
                    locationModels.cTLocationModels.Add(cTLocation);
                }
                var cTlocation = locationModels.cTLocationModels.FirstOrDefault(x => x.CaseType.ToLower() == casetypestr.ToLower());
                if (cTlocation != null)
                {
                    if (cTlocation.docLocations.Any())
                    {
                        locationModel = GetLastStage(doc, cTlocation.docLocations);
                    }

                }
            }
            return locationModel;
        }



    }
}
